#[macro_use]
extern crate rocket;
extern crate diesel;
extern crate diesel_migrations;
extern crate rocket_sync_db_pools;

mod auth;
mod db;
mod mapper;
mod models;
mod router;
mod schema;

use diesel_migrations::{
  embed_migrations, EmbeddedMigrations, MigrationHarness,
};
use rocket::{fairing::AdHoc, Build, Rocket};

use db::DbConn;
use router::*;

pub const MIGRATIONS: EmbeddedMigrations = embed_migrations!();

async fn run_db_migrations(
  rocket: Rocket<Build>,
) -> Result<Rocket<Build>, Rocket<Build>> {
  DbConn::get_one(&rocket)
    .await
    .expect("Failed to retrieve database connection.")
    .run(|conn| match conn.run_pending_migrations(MIGRATIONS) {
      Ok(_) => Ok(rocket),
      Err(e) => {
        eprintln!("Failed to run database migrations: {:?}", e);
        Err(rocket)
      }
    })
    .await
}

#[rocket::main]
async fn main() {
  // let server = rocket::build().mount("/", routes!(hello));
  let server = rocket::build()
    .mount(
      "/",
      routes![
        hello,
        get_todo,
        view_todo,
        create_todo,
        update_todo,
        delete_todo
      ],
    )
    .register("/", catchers![not_found])
    .attach(DbConn::fairing())
    .attach(AdHoc::try_on_ignite(
      "Rounning DB migrations",
      run_db_migrations,
    ));

  server.launch().await.unwrap();
}
